package com.way.fileexplorer.adapters;

import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import android.app.Activity;
import android.app.LoaderManager;
import android.app.ProgressDialog;
import android.content.ContentUris;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Loader;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio;
import android.provider.MediaStore.Images;
import android.provider.MediaStore.MediaColumns;
import android.provider.MediaStore.Video;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.ListView;

import com.way.fileexplorer.R;
import com.way.fileexplorer.util.FileSort;
import com.way.fileexplorer.util.FileType;
import com.way.fileexplorer.util.ImageLoader;
import com.way.fileexplorer.util.Slog;

public class QuickScanCursorAdapter extends FileAdapter implements View.OnClickListener {
    
    public static final int RESOURCE_VIDEO = 1;

    public static final int RESOURCE_IMAGE = 2;

    public static final int RESOURCE_AUDIO = 3;
    
    public static final int RESOURCE_DOC = 4;
    
    public static final int RESOURCE_APK = 5;

    private Activity mContext;

    private int mResourceType;

    private int mPathColumnIndex;
    
    private ListView mListView;

    private ImageLoader imageLoader;
    
    private boolean mIsSelectMode;
    
    private ProgressDialog mWaitDialog;
    
    private View mEmptyView;
    
    private boolean mTimeup = false;
    
    private boolean mLoadFinished = false;
    
    private int mPosition = 0;
    
    private Handler mHandler = new Handler();

    private Set mFileSet = new HashSet<File>();// bug 201834

    public QuickScanCursorAdapter(Activity context, int resourceType,
            String orderStr) {
        super(context);
        mResourceType = resourceType;
        mContext = context;
        refresh();
    }

    public QuickScanCursorAdapter(Activity context,int resourceType,
            View emptyView, ListView listview, boolean isSelectMode) {
        super(context);
        mResourceType = resourceType;
        mContext = context;
        imageLoader = new ImageLoader(mContext);
        mListView = listview;
        mListView.setOnScrollListener(onScrollListener);
        mIsSelectMode =  isSelectMode;
        mWaitDialog = showWaitDialog();
        WaitTimer mTimer = new WaitTimer(500,500);
        mTimer.start();
        mEmptyView = emptyView;
        refresh();
    }
    
    public QuickScanCursorAdapter(Activity context,int resourceType,
            int position, ListView listview, boolean isSelectMode) {
        super(context);
        mResourceType = resourceType;
        mContext = context;
        imageLoader = new ImageLoader(mContext);
        mListView = listview;
        mListView.setOnScrollListener(onScrollListener);
        mIsSelectMode =  isSelectMode;
        mWaitDialog = showWaitDialog();
        WaitTimer mTimer = new WaitTimer(500,500);
        mTimer.start();
        mPosition = position;
        refresh();
    }
    
    private LoaderManager.LoaderCallbacks<Cursor> mFileLoaderListener = new LoaderManager.LoaderCallbacks<Cursor>(){
        @Override
        public Loader<Cursor> onCreateLoader(int id, Bundle args) {
            // TODO Auto-generated method stub
            mListView.setEmptyView(null);
            String[] projection = new String[] { MediaColumns._ID,
                    MediaColumns.DATA, MediaColumns.TITLE,
                    MediaColumns.DATE_MODIFIED, MediaColumns.SIZE};
            String selection = null;
            Uri uri = null;
            final SharedPreferences sortPreference =  mContext.getSharedPreferences(
                    FileSort.FILE_SORT_KEY, 0);
            int sort = sortPreference.getInt(FileSort.FILE_SORT_KEY, FileSort.SORT_BY_NAME);
            
            String sortBy = FileSort.getOrderStr(sort);
            switch (mResourceType) {
            case RESOURCE_VIDEO:
                uri = Video.Media.EXTERNAL_CONTENT_URI;
                break;
            case RESOURCE_IMAGE:
                uri = Images.Media.EXTERNAL_CONTENT_URI;
                break;
            case RESOURCE_AUDIO:
                uri = Audio.Media.EXTERNAL_CONTENT_URI;
                break;
            case RESOURCE_DOC:
                uri = MediaStore.Files.getContentUri("external");
                selection = MediaStore.Files.FileColumns.DATA + " like '%.txt' or " +  MediaStore.Files.FileColumns.DATA + " like '%.log' or "
                        + MediaStore.Files.FileColumns.DATA + " like '%.doc' or " + MediaStore.Files.FileColumns.DATA + " like '%.pdf' or "
                        + MediaStore.Files.FileColumns.DATA + " like '%.ppt' or " + MediaStore.Files.FileColumns.DATA + " like '%pptx' or "
                        + MediaStore.Files.FileColumns.DATA + " like '%.xls' or " + MediaStore.Files.FileColumns.DATA + " like '%xlsx' or "
                        + MediaStore.Files.FileColumns.DATA + " like '%.docx'" ;
                break;
            case RESOURCE_APK:
                uri = MediaStore.Files.getContentUri("external");
                selection = MediaStore.Files.FileColumns.DATA + " like '%.apk'";
                break;
            }
            return new FileLoader(mContext, uri, projection, selection,sortBy);
        }

        @Override
        public void onLoadFinished(Loader<Cursor> loader, final Cursor data) {
            // TODO Auto-generated method stub
            if(data == null){
                Log.i(TAG,"data is null");
                return;
            }

            // bug 201834 begin
            final SharedPreferences settings = PreferenceManager
                    .getDefaultSharedPreferences(mContext);
            boolean display = settings.getBoolean("display_hide_file", false);

            if (data != null && !data.isClosed()) {
                mPathColumnIndex = data.getColumnIndexOrThrow(MediaColumns.DATA);
                mFileSet.clear();
                for (int i = 0; i < data.getCount() && data.moveToNext(); i++) {
                    String path = data.getString(mPathColumnIndex);
                    File file = new File(path);
                    if (display) {
                        if (file.exists()) {
                            mFileSet.add(file);
                        }
                    } else if (!file.isHidden()) {
                        if (file.exists()) {
                            mFileSet.add(file);
                        }
                    }
                }
                mFileList = new ArrayList<File>(mFileSet);
                notifyDataSetChanged();
            }
            // bug 201834 end
            else if (data.isClosed()) {
                refresh();
            }
            final SharedPreferences sortPreference =  mContext.getSharedPreferences(
                    FileSort.FILE_SORT_KEY, 0);
            int sort = sortPreference.getInt(FileSort.FILE_SORT_KEY, FileSort.SORT_BY_NAME);
            if(sort == FileSort.SORT_BY_TYPE || sort == FileSort.SORT_BY_TYPE_DESC){
                new Thread(new Runnable(){
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        FileSort.getFileListSort().sort(mFileList);
                        mHandler.post(new Runnable(){
                            @Override
                            public void run() {
                                // TODO Auto-generated method stub
                                notifyDataSetChanged();
                            }

                        });
                    }
                }).start();
            }
            mLoadFinished = true;
            if(mWaitDialog != null && mWaitDialog.isShowing() && mTimeup){
                mWaitDialog.dismiss();
                mListView.setEmptyView(mEmptyView);
                mListView.setSelection(mPosition);
                mTimeup=false;//bug 202707
            }
        }
        @Override
        public void onLoaderReset(Loader<Cursor> loader) {
            // TODO Auto-generated method stub
            
        }
        
    };

    public void refresh() {
        final SharedPreferences sortPreference =  mContext.getSharedPreferences(
                FileSort.FILE_SORT_KEY, 0);
        int sort = sortPreference.getInt(FileSort.FILE_SORT_KEY, FileSort.SORT_BY_NAME);
        int id = mResourceType * 10 + sort;
        mContext.getLoaderManager().restartLoader(id, null, mFileLoaderListener);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = super.getView(position, convertView, parent);
        ViewHolder vHolder = (ViewHolder) view.getTag(R.id.action_paste_mode_cancel);
        File file = mFileList.get(position);
        view.setTag(position);
        switch (mResourceType) {
        case RESOURCE_VIDEO:
            vHolder.fileIcon.setImageResource(FileType.getFileType(mContext).getVideoFileIcon(file));
            break;
        case RESOURCE_AUDIO:
            vHolder.fileIcon.setImageResource(FileType.getFileType(mContext).getAudioFileIcon(file));
            break;
        case RESOURCE_IMAGE:
            vHolder.fileIcon.setImageResource(R.drawable.file_item_image_ic);
            imageLoader.loadImage(position, file.getPath(), imageLoadListener,true);
            break;
        case RESOURCE_DOC:
            vHolder.fileIcon.setImageResource(FileType.getFileType(mContext).getDocFileIcon(file));
            break;
        case RESOURCE_APK:
            vHolder.fileIcon.setImageResource(R.drawable.file_item_apk_default_ic);
            imageLoader.loadImage(position, file.getPath(), imageLoadListener,false);
        }
        vHolder.fileIcon.setOnClickListener(this);
        if(mIsSelectMode){
            vHolder.selectCb.setVisibility(View.VISIBLE);
            if(isChecked(position)){
                vHolder.selectCb.setChecked(true);
            }else{
                vHolder.selectCb.setChecked(false);
            }
            vHolder.fileIcon.setClickable(false);
        }else{
            vHolder.selectCb.setVisibility(View.GONE);
            vHolder.fileIcon.setClickable(true);
        }
        return view;
    }

    ImageLoader.OnImageLoadListener imageLoadListener = new ImageLoader.OnImageLoadListener() {
        @Override
        public void onImageLoad(int position, Bitmap drawable) {
           View view = mListView.findViewWithTag(position);
            if (view != null) {
                ImageView iv = (ImageView) view.findViewById(R.id.file_icon);
                iv.setImageBitmap(drawable);
            }
        }

    };

    public void loadImage() {
        int start = mListView.getFirstVisiblePosition();
        int end = mListView.getLastVisiblePosition();
        if (end >= getCount()) {
            end = getCount() - 1;
        }
        imageLoader.setLoadLimit(start, end);
        imageLoader.unlock();
    }

    AbsListView.OnScrollListener onScrollListener = new AbsListView.OnScrollListener() {

        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            switch (scrollState) {
            case AbsListView.OnScrollListener.SCROLL_STATE_FLING:
                imageLoader.lock();
                break;
            case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
                loadImage();
                break;
            case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
                imageLoader.lock();
                break;
            default:
                break;
            }

        }

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem,
                int visibleItemCount, int totalItemCount) {
            // TODO Auto-generated method stub

        }
    };
    
    public Uri getFileUri(int position){
        Uri uri = MediaStore.Files.getContentUri("external");
        Cursor cursor = mContext.getContentResolver().query(uri, new String[]{MediaStore.Files.FileColumns._ID}, MediaStore.Files.FileColumns.DATA + "=?", new String[]{getFile(position).getPath()}, null);
        cursor.moveToFirst();
        long id = cursor.getLong(0);
	cursor.close();
        return ContentUris.withAppendedId(uri, id);
    }
    
    public File getFile(int position){
        return mFileList.get(position);
    }
    

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        switch (v.getId()) {
        case R.id.file_icon:
            ((View) v).showContextMenu();
            break;
        }
    }
    
    public void startSort() {
        if (null == mFileList || mFileList.isEmpty()) {
            return;
        }
        Slog.d("start sort");
        FileSort.getFileListSort().sort(mFileList);
    }
    
    public List<File> getFileList(){
        return mFileList;
    }
    private ProgressDialog showWaitDialog(){
        ProgressDialog dialog = new ProgressDialog(mContext);
        dialog.setTitle(R.string.dialog_hint_title);
        dialog.setMessage(mContext.getResources().getString(R.string.dialog_hint_msg));
        dialog.setCancelable(false);
        dialog.show();
        return dialog;
    }
    static class FileLoader extends CursorLoader{
        public FileLoader(Context context, Uri uri, String[] projection, String selection, String sort) {
            super(context, uri, projection, selection, null, sort);
            // TODO Auto-generated constructor stub
        }
    }
    
    class WaitTimer extends CountDownTimer{
        public WaitTimer(long millisInFuture, long countDownInterval) {
            super(millisInFuture, countDownInterval);
            // TODO Auto-generated constructor stub
        }

        @Override
        public void onTick(long millisUntilFinished) {
            // TODO Auto-generated method stub
            
        }

        @Override
        public void onFinish() {
            // TODO Auto-generated method stub
            mTimeup = true;
            if(mWaitDialog != null && mWaitDialog.isShowing() && mLoadFinished){
                mWaitDialog.dismiss();
                mListView.setEmptyView(mEmptyView);
                mListView.setSelection(mPosition);
                mLoadFinished = false;//bug 202707
            }
        }
    }
}
